<html>
<head><meta charset="utf-8"><title>Recursive type error: function vs closure · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Recursive.20type.20error.3A.20function.20vs.20closure.html">Recursive type error: function vs closure</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="212317736"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Recursive%20type%20error%3A%20function%20vs%20closure/near/212317736" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Recursive.20type.20error.3A.20function.20vs.20closure.html#212317736">(Oct 05 2020 at 15:43)</a>:</h4>
<p>Basically if you try and compile something like:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">with_foo</span><span class="o">&lt;</span><span class="n">R</span><span class="p">,</span><span class="w"> </span><span class="n">F</span><span class="o">&gt;</span><span class="w"> </span><span class="p">(</span><span class="w"></span>
<span class="w">    </span><span class="n">a</span>: <span class="kp">&amp;</span><span class="o">'</span><span class="nb">_</span> <span class="p">(),</span><span class="w"></span>
<span class="w">    </span><span class="n">_</span>: <span class="nc">F</span><span class="p">,</span><span class="w"></span>
<span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">R</span><span class="w"></span>
<span class="k">where</span><span class="w"></span>
<span class="w">    </span><span class="n">F</span><span class="w"> </span>: <span class="nc">for</span><span class="o">&lt;'</span><span class="na">local</span><span class="o">&gt;</span><span class="w"> </span><span class="nb">FnOnce</span><span class="p">(</span><span class="o">&amp;'</span><span class="na">local</span><span class="w"> </span><span class="p">())</span><span class="w"> </span>-&gt; <span class="nc">R</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="n">R</span><span class="w"> </span>: <span class="nb">Default</span><span class="p">,</span><span class="w"></span>
<span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">if</span><span class="w"> </span>::<span class="n">rand</span>::<span class="n">random</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">with_foo</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="o">|</span><span class="n">_</span>: <span class="kp">&amp;</span><span class="o">'</span><span class="nb">_</span> <span class="p">()</span><span class="o">|</span><span class="w"> </span><span class="p">());</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="n">R</span>::<span class="n">default</span><span class="p">()</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">main</span><span class="w"> </span><span class="p">()</span><span class="w"></span>
<span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">with_foo</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(),</span><span class="w"> </span><span class="o">|</span><span class="n">_</span><span class="o">|</span><span class="w"> </span><span class="p">());</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>

<p><a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=11d2236f9614b25fe19d7bd541632676">It fails with</a>:</p>
<div class="codehilite" data-code-language="Text only"><pre><span></span><code>error: reached the recursion limit while instantiating `with_foo::&lt;(), [closure@src/main.rs:10:21: 10:35]&gt;`
  --&gt; src/main.rs:10:9
   |
10 |         with_foo(a, |_: &amp;'_ ()| ());
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
</code></pre></div>

<p>But if instead of <code>|_: &amp;'_ ()| ()</code> you feed it <code>{ fn f(_: &amp;'_ ()) {}; f }</code>, <a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=b9f503ebdd6da67b1bf1d133beee1767">it compiles fine</a>!!!</p>
<p>My guess is that the type of the given closure, even if it does not capture any variable whatsoever, is somehow infected with the <code>F</code> parameter in scope, maybe? And that of course would lead to a recursive type</p>



<a name="212328955"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Recursive%20type%20error%3A%20function%20vs%20closure/near/212328955" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Recursive.20type.20error.3A.20function.20vs.20closure.html#212328955">(Oct 05 2020 at 17:09)</a>:</h4>
<blockquote>
<p>My guess is that the type of the given closure, even if it does not capture any variable whatsoever, is somehow infected with the F parameter in scope, maybe?</p>
</blockquote>
<p>That is correct. In fact this is one of the things polymorphization will help with.</p>



<a name="212329129"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Recursive%20type%20error%3A%20function%20vs%20closure/near/212329129" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Recursive.20type.20error.3A.20function.20vs.20closure.html#212329129">(Oct 05 2020 at 17:11)</a>:</h4>
<p>That makes me worry about effectively making polymorphization mandatory part of the language spec, since it affects whether code compiles or not</p>



<a name="212331083"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Recursive%20type%20error%3A%20function%20vs%20closure/near/212331083" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Recursive.20type.20error.3A.20function.20vs.20closure.html#212331083">(Oct 05 2020 at 17:29)</a>:</h4>
<p>Is there are a place where I can read about polymorphization [&amp; Rust]?</p>



<a name="212331117"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Recursive%20type%20error%3A%20function%20vs%20closure/near/212331117" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Recursive.20type.20error.3A.20function.20vs.20closure.html#212331117">(Oct 05 2020 at 17:29)</a>:</h4>
<p><a class="stream" data-stream-id="216091" href="/#narrow/stream/216091-t-compiler.2Fwg-polymorphization">#t-compiler/wg-polymorphization</a></p>



<a name="212331127"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Recursive%20type%20error%3A%20function%20vs%20closure/near/212331127" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Recursive.20type.20error.3A.20function.20vs.20closure.html#212331127">(Oct 05 2020 at 17:29)</a>:</h4>
<p>Duh, thanks <span aria-label="sweat smile" class="emoji emoji-1f605" role="img" title="sweat smile">:sweat_smile:</span></p>



<a name="212332844"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Recursive%20type%20error%3A%20function%20vs%20closure/near/212332844" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> lcnr <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Recursive.20type.20error.3A.20function.20vs.20closure.html#212332844">(Oct 05 2020 at 17:44)</a>:</h4>
<p><span class="user-mention silent" data-user-id="211727">Jonas Schievink</span> <a href="#narrow/stream/122651-general/topic/Recursive.20type.20error.3A.20function.20vs.20closure/near/212329129">said</a>:</p>
<blockquote>
<p>That makes me worry about effectively making polymorphization mandatory part of the language spec, since it affects whether code compiles or not</p>
</blockquote>
<p>well, this is already the case for mir opts</p>



<a name="212332880"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Recursive%20type%20error%3A%20function%20vs%20closure/near/212332880" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> lcnr <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Recursive.20type.20error.3A.20function.20vs.20closure.html#212332880">(Oct 05 2020 at 17:44)</a>:</h4>
<p>but polymorphization will indeed make this worse</p>



<a name="212333444"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Recursive%20type%20error%3A%20function%20vs%20closure/near/212333444" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Recursive.20type.20error.3A.20function.20vs.20closure.html#212333444">(Oct 05 2020 at 17:49)</a>:</h4>
<p>how so?</p>



<a name="212333538"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Recursive%20type%20error%3A%20function%20vs%20closure/near/212333538" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Recursive.20type.20error.3A.20function.20vs.20closure.html#212333538">(Oct 05 2020 at 17:50)</a>:</h4>
<p>I don't think we go from "does not compile regardless of recursion limit" to "compiles with defaults" because of any MIR opt</p>



<a name="212333565"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Recursive%20type%20error%3A%20function%20vs%20closure/near/212333565" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Recursive.20type.20error.3A.20function.20vs.20closure.html#212333565">(Oct 05 2020 at 17:50)</a>:</h4>
<p>And const prop warnings can be disabled</p>



<a name="212334599"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Recursive%20type%20error%3A%20function%20vs%20closure/near/212334599" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> lcnr <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Recursive.20type.20error.3A.20function.20vs.20closure.html#212334599">(Oct 05 2020 at 17:59)</a>:</h4>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">recurse</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">if</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">recurse</span>::<span class="o">&lt;</span><span class="p">(</span><span class="n">T</span><span class="p">,)</span><span class="o">&gt;</span><span class="p">()</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">recurse</span>::<span class="o">&lt;</span><span class="p">()</span><span class="o">&gt;</span><span class="p">();</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="212334724"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Recursive%20type%20error%3A%20function%20vs%20closure/near/212334724" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> lcnr <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Recursive.20type.20error.3A.20function.20vs.20closure.html#212334724">(Oct 05 2020 at 18:00)</a>:</h4>
<p>branch elim</p>



<a name="212335000"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Recursive%20type%20error%3A%20function%20vs%20closure/near/212335000" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> lcnr <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Recursive.20type.20error.3A.20function.20vs.20closure.html#212335000">(Oct 05 2020 at 18:02)</a>:</h4>
<p>fails with <code>mir-opt-level=0</code> compiles with <code>mir-opt-level=1</code></p>



<a name="212335048"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Recursive%20type%20error%3A%20function%20vs%20closure/near/212335048" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Recursive.20type.20error.3A.20function.20vs.20closure.html#212335048">(Oct 05 2020 at 18:02)</a>:</h4>
<p>Ah, right</p>



<a name="212407010"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Recursive%20type%20error%3A%20function%20vs%20closure/near/212407010" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Recursive.20type.20error.3A.20function.20vs.20closure.html#212407010">(Oct 06 2020 at 10:07)</a>:</h4>
<p>A final question: I'd like to refer to this "issue" / limitation / quirk (you name it) from within the scope of a PR that adds a <code>dyn Fn...</code> coercion to circumvent it. What's the canonical issue in the repo I should refer to?<br>
EDIT: there is <a href="https://github.com/rust-lang/rust/pull/69749">this PR</a>, but mentioning an already-merged PR that doesn't solve that particular issue does not feel right.</p>



<a name="212604850"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Recursive%20type%20error%3A%20function%20vs%20closure/near/212604850" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Recursive.20type.20error.3A.20function.20vs.20closure.html#212604850">(Oct 07 2020 at 19:07)</a>:</h4>
<p>FWIW, I've submitted <a href="https://github.com/rust-lang/rust/issues/77664">https://github.com/rust-lang/rust/issues/77664</a></p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>